﻿// HSS.Forms.MessageService.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       MessageService.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/24/2010
// ----------------------------------------------------------------------------
namespace HSS.Forms
{
	#region Using Directives
	using System;
	using System.Runtime.InteropServices;
	using System.Text;
	using System.Windows.Forms;
	#endregion

	#region MessageService
	/// <summary>
	/// Provide the ability to show various message boxes.
	/// </summary>
	public static class MessageService
	{
		#region ShowErrorDelegate
		/// <summary>
		/// A delegate for displaying a custom error message box
		/// </summary>
		/// <param name="ex">The exception to show</param>
		/// <param name="message">The error message to show</param>
		public delegate void ShowErrorDelegate(Exception ex, string message);
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the custom error reporter. If this property is null, the default
		/// messagebox is used.
		/// </summary>
		public static ShowErrorDelegate CustomErrorReporter
		{
			get { return _customErrorReporter; }
			set { _customErrorReporter = value; }
		} static ShowErrorDelegate _customErrorReporter;
		/// <summary>
		/// Gets or sets the MainForm of the current Application
		/// </summary>
		public static Form MainForm
		{
			get { return _mainForm; }
			set { _mainForm = value; }
		} static Form _mainForm;
		/// <summary>
		/// Gets or sets the default Title of the MessageBox (initial value is Application.ProductName )
		/// </summary>
		public static string DefaultMessageBoxTitle
		{
			get { return _defaultMessageBoxTitle; }
			set { _defaultMessageBoxTitle = value; }
		} static string _defaultMessageBoxTitle = Application.ProductName;
		/// <summary>
		/// Gets or sets whether or not to perform a MessageBeep when the MsgBox is shown.
		/// </summary>
		public static bool DoBeep
		{
			get;
			set;
		}
		#endregion

		#region Question
		/// <summary>
		/// Show a question message box
		/// </summary>
		/// <param name="question">The question to ask</param>
		/// <returns></returns>
		public static bool AskQuestion(string question)
		{
			return AskQuestion(StringParser.Parse(question), DefaultMessageBoxTitle);
		}
		/// <summary>
		/// Show a question message box
		/// </summary>
		/// <param name="question">The question to ask</param>
		/// <param name="title">The message box Title</param>
		/// <returns></returns>
		public static bool AskQuestion(string question, string title)
		{
			return MsgBox.Show(question, title,
								MsgBox.Buttons.YesNo,
								MsgBox.Icons.Question) == DialogResult.Yes;
		}
		/// <summary>
		/// Show a question message box
		/// </summary>
		/// <param name="title">The message box Title</param>
		/// <param name="formatstring">The source string to be formatted</param>
		/// <param name="formatitems">The inputs to be formatted</param>
		/// <returns></returns>
		public static bool AskQuestionFormatted(string title, string formatstring, params string[] formatitems)
		{
			return AskQuestion(Format(formatstring, formatitems), title);
		}
		/// <summary>
		/// Show a question message box
		/// </summary>
		/// <param name="formatstring">The source string to be formatted</param>
		/// <param name="formatitems">The inputs to be formatted</param>
		/// <returns></returns>
		public static bool AskQuestionFormatted(string formatstring, params string[] formatitems)
		{
			return AskQuestion(Format(formatstring, formatitems));
		}
		#endregion

		#region Message
		/// <summary>
		/// Show an informational message box
		/// </summary>
		/// <param name="message">The message to show</param>
		public static void ShowMessage(string message)
		{
			ShowMessage(message, DefaultMessageBoxTitle);
		}
		/// <summary>
		/// Show an informational message box
		/// </summary>
		/// <param name="message">The message to show</param>
		/// <param name="title">The message box Title</param>
		public static void ShowMessage(string message, string title)
		{
			MsgBox.Show(StringParser.Parse(message),
						StringParser.Parse(title),
						MsgBox.Buttons.OK,
						MsgBox.Icons.Information);
		}
		/// <summary>
		/// Show an informational message box
		/// </summary>
		/// <param name="formatString">The source string to be formatted</param>
		/// <param name="formatItems">The inputs to be formatted</param>
		public static void ShowMessageFormatted(string formatString, params string[] formatItems)
		{
			ShowMessage(Format(formatString, formatItems));
		}
		/// <summary>
		/// Show an informational message box
		/// </summary>
		/// <param name="title">The message box Title</param>
		/// <param name="formatString">The source string to be formatted</param>
		/// <param name="formatItems">The inputs to be formatted</param>
		public static void ShowMessageFormatted(string title, string formatString, params string[] formatItems)
		{
			ShowMessage(Format(formatString, formatItems), title);
		}
		#endregion

		#region Warning
		/// <summary>
		/// Show a warning message box
		/// </summary>
		/// <param name="message">The message to show</param>
		public static void ShowWarning(string message)
		{
			MessageService.ShowWarning(message, DefaultMessageBoxTitle);
		}
		/// <summary>
		/// Show a warning message box
		/// </summary>
		/// <param name="message">The message to show</param>
		/// <param name="title">The message box Title</param>
		public static void ShowWarning(string message, string title)
		{
			if (MessageService.MainForm == null)
			{
				MsgBox.Show(StringParser.Parse(message),
							StringParser.Parse(title),
							MsgBox.Buttons.OK,
							MsgBox.Icons.Warning);
			}
			else
			{
				MethodInvoker showWarning = delegate
				{
					MsgBox.Show(StringParser.Parse(message),
								StringParser.Parse(title),
								MsgBox.Buttons.OK,
								MsgBox.Icons.Warning);
				};
				if (MessageService.MainForm.InvokeRequired)
					MessageService.MainForm.BeginInvoke(showWarning);
				else
					showWarning();
			}
		}
		/// <summary>
		/// Show a warning message box
		/// </summary>
		/// <param name="formatstring">The source string to be formatted</param>
		/// <param name="formatitems">The inputs to be formatted</param>
		public static void ShowWarningFormatted(string formatstring, params string[] formatitems)
		{
			ShowWarning(Format(formatstring, formatitems));
		}
		/// <summary>
		/// Show a warning message box
		/// </summary>
		/// <param name="title">The message box Title</param>
		/// <param name="formatstring">The source string to be formatted</param>
		/// <param name="formatitems">The inputs to be formatted</param>
		public static void ShowWarningFormatted(string title, string formatstring, params string[] formatitems)
		{
			ShowWarning(Format(formatstring, formatitems), title);
		}
		#endregion

		#region Error
		/// <summary>
		/// Show an error message box
		/// </summary>
		/// <param name="ex">The exception to show</param>
		public static void ShowError(Exception ex)
		{
			ShowError(ex, null);
		}
		/// <summary>
		/// Show an error message box
		/// </summary>
		/// <param name="message">The error message to show</param>
		public static void ShowError(string message)
		{
			ShowError(null, message);
		}
		/// <summary>
		/// Show an error message box and write the error or exception to the HSS Log
		/// </summary>
		/// <param name="ex">The exception to show</param>
		/// <param name="message">The error message to show</param>
		public static void ShowError(Exception ex, string message)
		{
			if (_customErrorReporter != null)
			{
				_customErrorReporter(ex, message);
				return;
			}

			string msg = string.Empty;
			if (!string.IsNullOrEmpty(message))
				msg = message + "\n\n";

			if (ex != null)
				msg += "Exception occurred: " + ex.ToString();

			if (!string.IsNullOrEmpty(msg))
			{
				msg = StringParser.Parse(msg);

				string title = DefaultMessageBoxTitle;

				if (MessageService.MainForm == null)
					MsgBox.Show(msg, title, MsgBox.Buttons.OK, MsgBox.Icons.Error);
				else
				{
					MethodInvoker showError = delegate
					{
						MsgBox.Show(msg, title, MsgBox.Buttons.OK, MsgBox.Icons.Error);
					};

					if (MessageService.MainForm.InvokeRequired)
						MessageService.MainForm.BeginInvoke(showError);
					else
						showError();
				}
			}
		}
		/// <summary>
		/// Show an error message box
		/// </summary>
		/// <param name="formatstring">The source string to be formatted</param>
		/// <param name="formatitems">The inputs to be formatted</param>
		public static void ShowErrorFormatted(string formatstring, params string[] formatitems)
		{
			ShowError(null, Format(formatstring, formatitems));
		}
		#endregion

		#region Input
		/// <summary>
		/// Show an input message box
		/// </summary>
		/// <param name="title">The message box Title</param>
		/// <param name="prompt">The message box prompt</param>
		/// <param name="defaultValue">The default value</param>
		/// <returns>The users input, or an empty string if the user canceled the dialog</returns>
		public static string ShowInputBox(string title, string prompt, string defaultValue)
		{

			prompt = StringParser.Parse(prompt);
			title = StringParser.Parse(title);

			InputBoxResult res = InputBox.Show(prompt, title, defaultValue, null);

			if (res.OK)
				return res.Text;
			else
				return string.Empty;
		}
		#endregion

		#region Custom
		/// <summary>
		/// Show a message box with custom buttons.
		/// </summary>
		/// <param name="title">The Title for the message box</param>
		/// <param name="message">The message to show</param>
		/// <param name="acceptButtonIndex">Indicates the button that is the Forms AcceptButton</param>
		/// <param name="cancelButtonIndex">Indicates the button that is the Forms CancelButton</param>
		/// <param name="icon">The icon to show</param>
		/// <param name="buttontexts">A string array containing the text for the custom list of buttons</param>
		/// <returns>The index of the button that was pressed</returns>
		public static int ShowCustomDialog(string title, string message, int acceptButtonIndex, int cancelButtonIndex, MsgBox.Icons icon, params string[] buttontexts)
		{
			return MsgBox.Show(message, title, buttontexts, acceptButtonIndex, cancelButtonIndex, icon);
		}
		/// <summary>
		/// Show a message box with custom buttons.
		/// </summary>
		/// <param name="title">The Title for the message box</param>
		/// <param name="message">The message to show</param>
		/// <param name="icon">The icon to show</param>
		/// <param name="buttontexts">A string array containing the text for the custom list of buttons</param>
		/// <returns>The index of the button that was pressed</returns>
		public static int ShowCustomDialog(string title, string message, MsgBox.Icons icon, params string[] buttontexts)
		{
			return ShowCustomDialog(title, message, -1, -1, icon, buttontexts);
		}
		#endregion

		#region Formatting
		static string Format(string formatstring, string[] formatitems)
		{
			try
			{
				return String.Format(StringParser.Parse(formatstring), formatitems);
			}
			catch (FormatException)
			{
				StringBuilder b = new StringBuilder(StringParser.Parse(formatstring));
				foreach (string formatitem in formatitems)
				{
					b.Append("\nItem: ");
					b.Append(formatitem);
				}
				return b.ToString();
			}
		}
		#endregion

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		internal static extern bool MessageBeep(uint type);
	}
	#endregion
}